/*****************************************************************************/
/*                        >>> func_PPNIC.c-- <<<                             */
/*	Trabajo Practico 2do. cuatrimestre 2011                                  */
/*	TP:"FUSELAJE"                                                            */
/*	GRUPO: Reduce Fat Fast                                                   */
/*	INTEGRANTES: Emanuel Genovese                                            */
/*               Federico Gabriel Garcia                                     */
/*               Federico Pioli                                              */
/*               Esther Insfrain                                             */
/*               Luciano Bagattin                                            */
/*	Fecha UM:                                                                */
/*****************************************************************************/

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include "../headers/func_PPNIC.h"
#include "../headers/constantes.h"
#include "func_ipc.h"
#include "constants_commons.h"

/******************************************************************************/
/* Nombre de Funcion: fSendPPNIPCXsocket                                      */
/* Parametros: socket: socket por el cual se comunica                         */
/*             st: estructura que parseara para enviarlo a otros procesos     */
/*             log: archivo de log                                            */
/* Descripcion: Funcion que envia al Ppd la posicion del cabezal              */
/******************************************************************************/

int fSendPPNIPCXsocket(int iSocket, stNIPC st, void * sPayload, t_log * log) {
	/*declaracion de variables locales*/
	char *cadenaEnvio;
	int iOperados = -11, iTamanio, fEnvio_OK = 0, iSector;
	t_stream *t;

	/*fin de la declaracion de variables locales*/

	if (strcmp(st.sDescriptorOriginal, "NULL") == 0) {
		memcpy(st.sDescriptorOriginal, (char*) fGenerar_Desc_ID(), 16);
	} //fin del if

	switch (st.iPayloadDescriptor) {
	case POSICIONCABEZAL:
		/*cargamos la estructura nipc con la posicion del cabezal.*/

		t = stNIPC_serializer(&st, sPayload, stPosCabezal_serializer);
		break;
	case LECTURA:
		/*Cargamos la estructura de devolucion del trace.*/
		t = stNIPC_serializer(&st, sPayload, stRLecturaSector_serializer);
		break;
	case ESCRITURA:

		/*Cargamos la estructura con el resultado de la operacion de Escritura*/
		t = stNIPC_serializer(&st, sPayload, stREscrituraSector_serializer);
		break;
	case TRACE:
		t=stNIPC_serializer(&st, sPayload,stTrace_serializer);
		break;

	}
	/*Serializacion de la estructura de envio*/

	if (iSocket != -1) {
		while (fEnvio_OK == 0) {
			if ((iOperados = send(iSocket, t->data, t->length, 0)) == -1) {

				fEnvio_OK = 2;
			}
			if (t->length == iOperados)
				fEnvio_OK = 1;
			if (iOperados == 0)
				fEnvio_OK = 2;
		} //fin del while

		if (fEnvio_OK == 2)
			iOperados = -1;
	} //fin del if

	return (iOperados == -1) ? 0 : iOperados;
} //fin del fSendIPCCXsocket

/******************************************************************************/
/* Nombre de Funcion: fRecvPPNIPCXsocket                                      */
/* Parametros: socket: socket por el cual se comunica                         */
/*             stR: estructura donde parseara todo lo qeu le envia el PPD     */
/*               log: archivo de log                                          */
/* Descripcion: Funcion que envia al Ppd la posicion del cabezal              */
/******************************************************************************/

int fRecvPPNIPCXsocket(int iSocket, stNIPC *stPedido, void ** sPayload,
		t_log * log) {
	/*declaracion de variables locales*/
	char *cadHeader;
	char *cadPayload = NULL;
	char stcadena[1024] = "\0";
	int iMaxBuffer, iOperados, iFlag = 0;
	stPEscrituraSector *stPE=NULL;
	stPEscrituraSector stP;
	int *sL=NULL;
	int iSectorALeer;

	t_stream * p = (t_stream*) malloc(sizeof(t_stream));
	t_stream * q = (t_stream*) malloc(sizeof(t_stream));

	/*fin de la declaracion de variables locales*/

	iMaxBuffer = sizeof(stNIPC);
	cadHeader = (char *) malloc(iMaxBuffer);

	while ((iOperados = recv(iSocket, cadHeader, iMaxBuffer, MSG_PEEK))
				==iMaxBuffer) {
			iMaxBuffer += 512;
			cadHeader = realloc(cadHeader, iMaxBuffer);

	} //fin del while

	iOperados = recv(iSocket, cadHeader, iMaxBuffer, 0);


	if ((iOperados == -1) || (iOperados == 0)) {
		log_error(log,
				SNOMBREPROCESO,
				"Message error: %s",
				"Error en el recv del header de la struct NIPC enviado por Consola/PFS/PRAID");

		iFlag = 0;
		iOperados = -1;
	} //fin del if

	log_info(
			log,
			SNOMBREPROCESO,
			"Message info: %s",
			"Exito  en el recv del header de la struct NIPC enviado por Consola/PFS/PRAID");
	p->data = cadHeader;
	p->length = iMaxBuffer;
	stNIPC_deserializer(p, stPedido);
	memset(stcadena, '\0', 1024);

	if (stPedido->sPayload_lenth > 0) {

		cadPayload = (char*) malloc(stPedido->sPayload_lenth);

		memcpy(cadPayload, cadHeader + 26, stPedido->sPayload_lenth);



		iFlag=1;
		q->data = cadPayload;
		q->length =  stPedido->sPayload_lenth;
	} //fin del if

	memset(stcadena, '\0', 1024);

	if (iFlag) {

		switch (stPedido->iPayloadDescriptor) {

		case ESCRITURA:

			 stPEscrituraSector_deserializer(q, &stPE);
			 stP=*stPE;
			 *sPayload=&stP;
			break;
		case LECTURA:case TRACE:
			stPLecturaSector_deserializer(q, &sL);
            iSectorALeer=*sL;
            *sPayload=(void *)&iSectorALeer;

			break;

		} //fin del switch

	} //fin del if
	memset(stcadena, '\0', 1024);

	return (iOperados == -1) ? 0 : iOperados;
} //fin del fRecvIPCCXsocket
